#include <attribute.h>
#include <assert.h>
#include <sstream>

Attribute::Attribute ()
{	
	m_cData = NULL;
	m_iLength = 0;
	m_iFree = 3;
}
Attribute::~Attribute ()
{
	if(m_iFree == 1)
	{
		if(m_cData && m_cData != NULL)
		{
			delete [] (char*)m_cData;
			m_iFree = 3;
		}
	}
	//to do:: need to delete data here.. else its a leaky bucket.
	//m_cData = NULL;
}
void Attribute:: FreeMem()
{
	if(m_cData && m_cData != NULL)
	{
		delete [] (char*)m_cData;
		m_iFree = 3;
	}
}	
void Attribute:: SetFree()
{
	m_iFree = 1;
}
void Attribute:: Free()
{
	m_iFree = 2;
}
void Attribute:: SetData(string _cPtr , Type _type)
{
	//Free();
	switch(_type)
	{
		case Int:
		{
			m_iLength = sizeof(int);
			m_cData   = new char[m_iLength];
			int x     = atoi(_cPtr.c_str());
			memmove(m_cData, &x, sizeof(int));
			break;
		}
		case Double:
		{	
			m_iLength = sizeof(double);
			m_cData   = new char[m_iLength];
			double x     = atof(_cPtr.c_str());
			memmove(m_cData, &x, sizeof(double));
			break;
		}
		case String:
		{
			m_cData = new char[_cPtr.length() + 1];
			memset(m_cData, '\0', _cPtr.length() + 1 );
			_cPtr.copy((char*)m_cData, _cPtr.length() + 1);
			m_iLength = strlen((char*)m_cData)+1;
			break;
		}
		default:
			cout<<"default:"<<__LINE__<<endl;
			break;
	}
}

int Attribute::ToBinary(char* _cWriteToHere)
{

	assert(_cWriteToHere);
	memmove(_cWriteToHere,&m_iLength, sizeof(int));
	char * temp = _cWriteToHere + sizeof(int);
	memmove(temp,(char*)m_cData, m_iLength);
	return (m_iLength + sizeof(int)) ;	
}

int Attribute:: FromBinary (char* _cReadFromHere)
{
	int iLen;
	assert(_cReadFromHere);

	memmove(&iLen, (int*)_cReadFromHere, sizeof(int)); 
	m_cData = new char[iLen]; 
	char * temp = _cReadFromHere + sizeof(int);
	memmove(m_cData,temp,iLen);
 	m_iLength = iLen; 

	return (m_iLength + sizeof(int));
}


void Attribute::Print(Type _type)
{
	assert(m_cData);

	if(m_cData == NULL)
	{
		cout << "NULL" << endl;
	}
	else
	{
		switch(_type)
		{

		  case Int:
			printf("%i",*(int*)m_cData);
		  	break;
		  case Double: 
			printf("%.2f",*(double*)m_cData);
		  	break;
		  case String:
			printf("%s",(char*)m_cData);;
		  	break;
		  default:
			cout<<"default:"<<__LINE__<<endl;
			break;
		}

	}
}

int Attribute::GetBytes()
{
	return m_iLength;
}

void Attribute::ClearData()
{
	m_cData = NULL;
	m_iFree = 2;
}
int Attribute::Compare(Attribute at, Type _ty, int _compare)
{
	int ret = 1;
	if(_ty == Int)
	{
		//printf("%i \n",*(int*)m_cData);
		//printf("%i \n",*(int*)at.m_cData);
		if(_compare == 0)
		{
			if(*(int*)at.m_cData == *(int*)m_cData)
			{
				ret = 1;
			}
			else
			{
				ret = 0;
			}
		}
		else if(_compare == 1)
		{
			if(*(int*)m_cData < *(int*)at.m_cData)
			{
				ret = 1;
				//cout << "Here"<<endl;
			}
			else
			{
				ret = 0;
			}
		}
		else
		{
			if(*(int*)m_cData > *(int*)at.m_cData)
			{
				ret = 1;
			}
			else
			{
				ret = 0;
			}
		}
	}
	else if(_ty == Double)
	{
		//printf("%.2f \n",*(double*)at.m_cData);
		//printf("%.2f \n",*(double*)m_cData);
		if(_compare == 0)
		{
			if(*(double*)at.m_cData == *(double*)m_cData)
			{
				ret = 1;
			}
			else
			{
				ret = 0;
			}
		}
		else if(_compare == 1)
		{
			if(*(double*)m_cData < *(double*)at.m_cData)
			{
				ret = 1;
				//cout << "Here"<<endl;
			}
			else
			{
				ret = 0;
			}
		}
		else
		{
			if(*(double*)m_cData > *(double*)at.m_cData)
			{
				ret = 1;
				//cout << "Here"<<endl;
			}
			else
			{
				ret = 0;
			}		
		}
	}
	else
	{
		//cout<<"["<<(char*)at.m_cData<<"] "<<endl;
		//cout<<"["<<(char*)m_cData<<"] "<<endl;
		if(_compare == 0)
		{
			//if(strcmp ((char*)m_cData,(char*)at.m_cData) == 0)
			if(strcasecmp ((char*)m_cData,(char*)at.m_cData) == 0)
			{
				ret = 1;
			}
			else
			{
				ret = 0;
			}
		}
		else if(_compare == 1)
		{
			//if(strcmp ((char*)m_cData,(char*)at.m_cData) < 0)
			if(strcasecmp ((char*)m_cData,(char*)at.m_cData) < 0)
			{
				ret = 1;
				//cout << "Here"<<endl;
			}
			else
			{
				ret = 0;
			}
		}
		else
		{
			//if(strcmp ((char*)m_cData,(char*)at.m_cData) > 0)
			if(strcasecmp ((char*)m_cData,(char*)at.m_cData) > 0)
			{
				ret = 1;
				//cout << "Here"<<endl;
			}
			else
			{
				ret = 0;
			}		
		}

	}
	return ret;
}
